import { Injectable } from '@angular/core';
import { SelectionModel } from '@angular/cdk/collections';
import { Observable, Subject } from 'rxjs';
import { findIndex as _findIndex } from 'lodash';
import { LvSelectSM, LvSizeLSD, TypeUtils } from '../core/api';

@Injectable()
export class SelectService {
  panelClass: any;
  selection: SelectionModel<any>; // 选中
  defaultVirtualItemSizeConfig = {
    large: 40,
    default: 32,
    small: 24,
  };

  private typeUtils = TypeUtils;
  private _mode: LvSelectSM = 'single'; // 模式
  private _refresh$ = new Subject<void>(); // 广播更新脏值检查流

  constructor() {}

  getMode(): LvSelectSM {
    return this._mode;
  }

  setReFresh(): void {
    this._refresh$.next();
  }

  getPanelClass(): any {
    return this.panelClass;
  }

  setMode(value: LvSelectSM): void {
    this._mode = value;
  }

  setPanelClass(value: any): void {
    this.panelClass = value;
  }

  isMultipleMode(): boolean {
    return this._mode === 'multiple';
  }

  toggleSelection(value: any): void {
    this.selection.toggle(value);
  }

  getRefresh(): Observable<any> {
    return this._refresh$.asObservable();
  }

  initSelection(multiple: boolean, value: any): void {
    this.selection = new SelectionModel(multiple, value);
  }

  getActiveNodeFirstIndex(data: any[]): any {
    return _findIndex(data, (item): any => item.active || item.selected);
  }

  getScrollY(lvScroll: { x?: string | null; y?: string | null }, lvSize: LvSizeLSD): string {
    const max = 9;
    const scrollY = lvScroll?.y;
    return scrollY ? scrollY : `${this.defaultVirtualItemSizeConfig[lvSize] * max}px`;
  }

  getTargetPath(source: Array<any>): Array<any> {
    const path: any = [source];
    let i = 0;
    let x;

    while (this.typeUtils.isNotNil((x = path[i++].parentNode))) {
      path.push(x);
    }
    return path;
  }
}
